
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Logger;

//@author A0105195J

public class PopUp {
	private static final String HTML_TEXT_STYLE = "<html><i><font face = 'Comic Sans' color='white' size = '2.1'>";
	private static final int DESRIPTION_FONT_TYPE = 2;
	private static final int FONT_SIZE = 15;
	private static final int HEADER_FONT_TYPE = 1;
	private static final int MAX_ALLOWED_LENGTH_OF_DESCRIPTION = 36;
	private static final int LENGTH_OF_FRAME = 39;
	private static final String DEADLINE_KEYWORD = "   BY  ";
	private static final String EVENT_KEYWORD_2 = "  TO  ";
	private static final String EVENT_KEYWORD_1 = "  FROM  ";
	private static final int END_INDEX_OF_TIME = 16;
	private static final int START_INDEX_OF_TIME = 3;
	private static final String SNOOZE = "Snooze";
	private static final int MESSAGE_HEADER_INDEX = 0;
	private static final int MESSAGE_LENGTH_FOR_EVENTS = 5;
	private static final int MESSAGE_LENGTH_FOR_DEADLINES = 3;
	private static final int DEADLINE_COLOR_CODE = 1;
	private static final int EVENT_COLOR_CODE = 0;
	private static final int MISC_COLOR_CODE = 2;

	private static int currentColor;
	private static Logger logger = Logger.getLogger("Log for Pop Up reminder");

	public static void runPopUp(Task TaskWithEarliestReminder) {
		if (isTimeForReminder(TaskWithEarliestReminder)) {
			String formattedDescrip = formatDescription(TaskWithEarliestReminder
					.getDescription());
			popUpReminder(formattedDescrip,
					TaskWithEarliestReminder.getTimeSpan());

			Functions.deleteShownReminder(TaskWithEarliestReminder);

		}
	}

	private static String formatDescription(String description) {
		description.replaceAll("\\s+", " ");
		if (description.length() > LENGTH_OF_FRAME) {
			description = description.substring(0,
					MAX_ALLOWED_LENGTH_OF_DESCRIPTION);
			description += "...";
		}
		return description;
	}

	public static boolean isTimeForReminder(Task t) {
		return (Calendar.getInstance().getTime().after(t.getReminder()
				.getReminderTime()));
	}

	public static void popUpReminder(String message, TimeSpan timeSpan) {

		message += addDateToMessage(timeSpan);
		prepareReminder(message, SNOOZE);
	}

	public static String addDateToMessage(TimeSpan timeSpan) {
		if (timeSpan.isDeadline()) {
			currentColor = DEADLINE_COLOR_CODE;
			return DEADLINE_KEYWORD + parseDate(timeSpan.getStart());
		} else if (timeSpan.isEvent()) {
			currentColor = EVENT_COLOR_CODE;
			return EVENT_KEYWORD_1 + parseDate(timeSpan.getStart())
					+ EVENT_KEYWORD_2 + parseDate(timeSpan.getEnd());
		} else {
			currentColor = MISC_COLOR_CODE;
			return ""; // no date to add for a misc task
		}
	}

	public static String parseDate(Date D) {
		String dateInString = D.toString();
		dateInString = dateInString.substring(START_INDEX_OF_TIME,
				END_INDEX_OF_TIME);
		return dateInString;

	}

	public static void prepareReminder(String message, String header) {

		String messages[] = message.split("  ");
		JFrame frame = new JFrame();
		frame = addFrameAttributes(frame);

		GridBagConstraints headerConstraints = new GridBagConstraints();
		computeHeaderConstraints(headerConstraints);
		addHeaderToFrame(header, frame, headerConstraints);

		GridBagConstraints descripConstraints = new GridBagConstraints();
		computeDescriptionConstraints(descripConstraints);
		JPanel messagePanel = createMsgPanel();
		addDescriptionToPanel(messages, headerConstraints, descripConstraints,
				messagePanel);

		addPanelToFrame(frame, descripConstraints, messagePanel);

		frame.setVisible(true);
		logger.info("Reminder Popped up");

		exitOnEsc(frame);
	}

	public static void addPanelToFrame(JFrame frame,
			GridBagConstraints descripConstraints, JPanel messagePanel) {
		frame.add(messagePanel, descripConstraints);
	}

	public static void addDescriptionToPanel(String[] messages,
			GridBagConstraints headerConstraints,
			GridBagConstraints descripConstraints, JPanel messagePanel) {
		addDescriptionHeaderToPanel(messages[MESSAGE_HEADER_INDEX],
				headerConstraints, descripConstraints, messagePanel);
		addTimeToPanel(messages, descripConstraints, messagePanel);
	}

	public static void exitOnEsc(final JFrame frame) {
		frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
				.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "EXIT");
		frame.getRootPane().getActionMap().put("EXIT", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				frame.setVisible(false);
			}
		});
	}

	public static void addDescriptionHeaderToPanel(String message,
			GridBagConstraints headerConstraints,
			GridBagConstraints descripConstraints, JPanel messagePanel) {
		JLabel messageText = new JLabel(message);
		addMsgDescription(headerConstraints, descripConstraints, messagePanel,
				messageText);
	}

	public static void addTimeToPanel(String[] messages,
			GridBagConstraints descripConstraints, JPanel messagePanel) {
		if (messages.length == MESSAGE_LENGTH_FOR_EVENTS) {
			addTimeForEvents(messages, descripConstraints, messagePanel);
		} else if (messages.length == MESSAGE_LENGTH_FOR_DEADLINES) {
			addTimeForDeadlines(messages, descripConstraints, messagePanel);
		}
	}

	public static JPanel createMsgPanel() {
		JPanel messagePanel = new JPanel();
		messagePanel.setLayout(new GridBagLayout());
		messagePanel.setBackground(getCurrentColor());
		return messagePanel;
	}

	private static Color getCurrentColor() {
		if (currentColor == EVENT_COLOR_CODE)
			return getLightBlueColor();
		else if (currentColor == DEADLINE_COLOR_CODE)
			return getRedColor();
		else
			return getDarkGreenColor();
	}

	public static Color getLightBlueColor() {
		return Color.getHSBColor(124.0f / 255, 255.0f / 255, 122.0f / 255);
	}

	public static Color getDarkGreenColor() {
		return Color.getHSBColor(83.0f / 255, 255.0f / 255, 96.0f / 255);
	}

	public static Color getRedColor() {
		return Color.getHSBColor(8.0f / 255, 255.0f / 255, 144.0f / 255);
	}

	public static void addMsgDescription(GridBagConstraints headerConstraints,
			GridBagConstraints descripConstraints, JPanel messagePanel,
			JLabel messageText) {
		messageText.setForeground(Color.white);
		messageText
				.setFont(new Font("Calibri", DESRIPTION_FONT_TYPE, FONT_SIZE));
		messagePanel.add(messageText, headerConstraints);
		descripConstraints.gridy++;
	}

	public static void addTimeForDeadlines(String[] messages,
			GridBagConstraints descripConstraints, JPanel messagePanel) {
		messagePanel.add(new JLabel(HTML_TEXT_STYLE + messages[1] + " "
				+ messages[2]), descripConstraints);
	}

	public static void addTimeForEvents(String[] messages,
			GridBagConstraints descripConstraints, JPanel messagePanel) {
		messagePanel.add(new JLabel(HTML_TEXT_STYLE + messages[1] + " "
				+ messages[2] + " " + messages[3] + messages[4]),
				descripConstraints);
	}

	public static void addHeaderToFrame(String header, JFrame frame,
			GridBagConstraints constraints) {
		JLabel headingLabel = new JLabel(header);
		headingLabel.setForeground(Color.white);
		headingLabel.setFont(new Font("Verdana", HEADER_FONT_TYPE, FONT_SIZE));
		frame.add(headingLabel, constraints);
	}

	public static void computeDescriptionConstraints(
			GridBagConstraints constraints) {
		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.weightx = 1.0f;
		constraints.insets = new Insets(5, 10, 5, 10);
	}

	public static void computeHeaderConstraints(GridBagConstraints constraints) {
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.weightx = 1.0f;
		constraints.weighty = 0.0f;
		constraints.insets = new Insets(0, 10, 5, 10);
	}

	public static JFrame addFrameAttributes(JFrame frame) {

		frame.setSize(300, 115);
		setFramePosition(frame);
		setFrameColor(frame, currentColor);
		setFrameFeatures(frame);
		return frame;

	}

	public static void setFrameFeatures(JFrame frame) {
		frame.setResizable(false);
		frame.setUndecorated(true);
		frame.setAlwaysOnTop(true);
		frame.setAutoRequestFocus(true);
		frame.setLayout(new GridBagLayout());

	}

	public static void setFramePosition(JFrame frame) {
		Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); // get
		// size
		// of
		// the
		// screen
		Insets toolHeight = Toolkit.getDefaultToolkit().getScreenInsets(
				frame.getGraphicsConfiguration());// height of the task bar
		frame.setLocation(scrSize.width - frame.getWidth(), scrSize.height
				- toolHeight.bottom - frame.getHeight());
	}

	public static void setFrameColor(JFrame frame, int colorCode) {
		if (colorCode == EVENT_COLOR_CODE)
			frame.getContentPane().setBackground(getLightBlueColor());
		else if (colorCode == DEADLINE_COLOR_CODE)
			frame.getContentPane().setBackground(getRedColor());
		else
			frame.getContentPane().setBackground(getDarkGreenColor());

	}

}
